package beans.factory.support;

import beans.BeansException;
import beans.factory.FactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description: TODO 关于 FactoryBean 此类对象的注册操作
 * @Author: Take-off
 * @Date: 2023/2/26 4:12 PM
 * @Param
 * @return
 * @Version: 1.0
 **/
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{

    /**
     * 缓存操作 factoryBeanObjectCache
     **/
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>();

    /**
     * @Description: //TODO 从缓存中获取对象
     * @Author: Take-off
     * @Date: 4:20 PM 2023/2/26
     * @Param: [beanName]
     * @return: java.lang.Object
     **/
    protected Object getCachedObjectForFactoryBean(String beanName) {
        Object object = this.factoryBeanObjectCache.get(beanName);
        return (object != NULL_OBJECT ? object : null);
    }

    /**
     * @Description: //TODO 缓存没有，直接创建
     * @Author: Take-off
     * @Date: 4:20 PM 2023/2/26
     * @Param: [factory, beanName]
     * @return: java.lang.Object
     **/
    protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
        if (factory.isSingleton()) {
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                object = doGetObjectFromFactoryBean(factory, beanName);
                this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
            }
            return (object != NULL_OBJECT ? object : null);
        } else {
            return doGetObjectFromFactoryBean(factory, beanName);
        }
    }

    /**
     * @Description: //TODO 具体的获取 FactoryBean#getObject() 方法
     * @Author: Take-off
     * @Date: 4:20 PM 2023/2/26
     * @Param: [factory, beanName]
     * @return: java.lang.Object
     **/
    private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
        try {
            return factory.getObject();
        } catch (Exception e) {
            throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
        }

    }



}
